package com.intretech.umsin.oss.service.impl;

import com.intretech.umsin.oss.entity.FileType;
import com.intretech.umsin.oss.service.MetadataStoreService;
import com.intretech.umsin.oss.util.huaweiobs.HuaweiOssProperties;
import com.intretech.umsin.oss.util.huaweiobs.ObsTemplate;
import com.intretech.umsin.oss.vo.FileInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 * @version V1.0
 * @ClassName: HuaweiOssServiceImpl
 * @Description: HuaweiOssServiceImpl 服务实现
 * @author: 李启联
 * @date: 2022-04-25 16:26
 * @Copyright: Copyright (c) 2022
 */
@Service
@Slf4j
public class HuaweiOssServiceImpl extends AbstractFileService {

    @Autowired(required = false)
    private MetadataStoreService metadataStoreService;

    @Autowired
    private HuaweiOssProperties obsProperties;

    @Autowired(required = false)
    private ObsTemplate obsTemplate;


    /**
     * OSS存储类型
     *
     * @return
     */
    @Override
    public FileType fileType() {
        return FileType.HUAWEI;
    }

    /**
     * 文件元数据存储服务
     *
     * @return
     */
    @Override
    protected MetadataStoreService getMetadataStoreService() {
        return metadataStoreService;
    }

    /**
     * 上传文件
     *
     * @param file
     * @param fileInfo
     */
    @Override
    protected void uploadFile(MultipartFile file, FileInfoVo fileInfo) throws Exception {
        String workDir = processPathStartWithBlank(processPathEndWithBlank(obsProperties.getWorkDir()));
        if(fileInfo.getFilePathPrefix().length() >1){//设置文件的路径前缀
            String prefix = processPathStartWithBlank(fileInfo.getFilePathPrefix());
            fileInfo.setFilePathPrefix(workDir +"/"+prefix);
        }else{
            fileInfo.setFilePathPrefix(workDir);
        }
        String objectKey = processPathStartWithBlank(processPathEndWithBlank(fileInfo.getFilePathPrefix())+"/"+fileInfo.getTagsName());

        obsTemplate.putObjectAndSetPreAccessStrategy(objectKey,file.getInputStream());
    }

    /**
     * 删除文件资源
     *
     * @param fileInfo
     * @return
     */
    @Override
    protected boolean deleteFile(FileInfoVo fileInfo) {
        String objectKey =processPathStartWithBlank(fileInfo.getPath());
        return obsTemplate.deletObj(objectKey).isDeleteMarker();
    }

    /**
     * 对查询返回的文件列表设置其对应文件访问的URL
     *
     * @param fileInfo
     */
    @Override
    protected void setFileUrl(FileInfoVo fileInfo) {
        fileInfo.setUrl(obsTemplate.getSignedUrl(processPathStartWithBlank(fileInfo.getPath())));
    }

    /**
     * 下载文件
     *
     * @param fileInfo
     * @return
     */
    @Override
    public byte[] downloadFile(FileInfoVo fileInfo) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        InputStream inputStream = null;
        try {
            String objectKey = processPathStartWithBlank(fileInfo.getPath());
            inputStream = obsTemplate.getObjectInpuStream(objectKey);
            IOUtils.copy(inputStream,bos);
            return bos.toByteArray();
        }catch (Exception e) {
            log.error("download file error!", e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return null;
    }


    private String processPathEndWithBlank(String path) {
        path = path.replace("\\", "/").replace("//", "/");
        path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
        if(path.equals("/")){
            return "";
        }
        return path;
    }

    private String processPathStartWithBlank(String path) {
        path = path.replace("\\", "/").replace("//", "/");;
        path = path.startsWith("/") ? path.substring(1,path.length()) :  path;
        if(path.equals("/")){
            return "";
        }
        return path;
    }
}
